/*
    AIP650.cpp 驱动aip650四位数码管
    木牛流马-华休
    2020年11月2号
*/

#include "AIP650.h"
#include <Arduino.h>

//  --0x01--
// |        |
//0x20     0x02
// |        |
//  --0x40- -
// |        |
//0x10     0x04
// |        |
//  --0x08--

//数码管字符表
static uint8_t tube_tab[] = {0x3f, 0x06, 0x5b, 0x4f,
                            0x66, 0x6d, 0x7d, 0x07,
                            0x7f, 0x6f, 0x77, 0x7c,
                            0x39, 0x5e, 0x79, 0x71
                           }; //0~9,A,b,C,d,E,F


// 引脚初始化清空显示
void AIP650::init(uint8_t clk, uint8_t data) 
{
    clkpin = clk;
    datapin = data;
    pinMode(clkpin, OUTPUT);
    pinMode(datapin, OUTPUT);
    clearDisplay();
}

//发送一个8bit数据到aip650
void AIP650::writeByte(uint8_t wr_data) 
{
    // 发送一个8bit数据
    for (uint8_t i = 0; i < 8; i++) 
    { 
        
        digitalWrite(clkpin, LOW);
        bitDelay();
        if ((wr_data & (0x80>>i))==0) 
        {
            digitalWrite(datapin, LOW);
        } 
        else 
        {
            digitalWrite(datapin, HIGH);
        }
        bitDelay();
        digitalWrite(clkpin, HIGH);
        bitDelay();
    }

    digitalWrite(clkpin, LOW); 
    bitDelay();
    digitalWrite(datapin, LOW);
    bitDelay();
    digitalWrite(clkpin, HIGH);
    bitDelay();
}

// 开始信号
void AIP650::start(void) {
    digitalWrite(clkpin, HIGH);
    digitalWrite(datapin, HIGH);
    bitDelay();
    digitalWrite(datapin, LOW);
    bitDelay();
}

// 结束信号
void AIP650::stop(void) {
    digitalWrite(clkpin, LOW);
    bitDelay();
    digitalWrite(datapin, LOW);
    bitDelay();
    digitalWrite(clkpin, HIGH);
    bitDelay();
    digitalWrite(datapin, HIGH);
}

//写入地址和数据
void AIP650::writeBytes(uint8_t adr,uint8_t dat)
{
    start();
    writeByte(adr);
    writeByte(dat);
    stop();
}
//index:显示第几位数1-4；num:数值0-9；show_dot:是否显示小数点；light:亮度1-8，改变四位同时改变。
// void AIP650::showNum(int8_t index,int8_t num,bool show_dot=false,int8_t light=8)
// {
//     if(index<1||index>4)
//     {
//         index=1;
//     }
//     setShowLight(light);
//     bitDelay();
//     int8_t show_data=tube_tab[num];
//     if(show_dot)
//     {
//         show_data=show_data|0x80;
//     }
//     writeBytes(0x66+index*2,show_data);
// }
//index:显示第几位数1-4；num:数值0-9  0-F   ；show_dot:是否显示小数点；light:亮度1-8，改变四位同时改变。
void AIP650::showNum(uint8_t index,uint8_t num,bool show_dot)
{
    if(index<1||index>4)
    {
        index=1;
    }
    setShowLight(showLight);
    bitDelay();
    int8_t show_data=tube_tab[num];
    if(show_dot)
    {
        show_data=show_data|0x80;
    }
    writeBytes(0x66+index*2,show_data);
}

//light:亮度1-8，改变四位同时改变。
void AIP650::setShowLight(uint8_t light)
{
     if(light==8)
    {
        writeBytes(0x48,0x01);//最亮
    }
    else
    {
        writeBytes(0x48,0x01+0x10*light);//亮度变化
    }
    showLight=light;//记录一下
}

// //显示数字
// void AIP650::showNum(String str)
// {
//    uint8_t dotIndex=str.IndexOf(".");
   
//     if(str.length()>5)
//     {
//         str=str.Substring(0,5);
//     }

    

// }



//显示
void AIP650::displayString(char *aString)
{
    uint8_t buf[5],k=0;//buf用于存贮小数点的位置，4个小数点位，buf[0]无用
    memset(buf,100,5);//
    unsigned int slen = strlen(aString) > 49 ? 49 : strlen(aString);//如果大于49就返回49，否则就返回长度
    char cString[50];
    memcpy(cString, aString, slen);//复制字符串到cString，最多复制49个？
    cString[slen] = '\0';//添加结束符

    for(int i=0; i<slen; i++)
    {
        //判断是否等于小数点 char（46）=.
        if(cString[i] == 46 && i != 0)
        {
            if(cString[i-1] != 46)
            {
                if(i<5)
                {
                    buf[k++]=i;//buf[0]=i第几位是小数点 1,2,3,4
                }        
                for(int j=i; j<slen-1; j++)
                {
                    cString[j] = cString[j+1];//把小数点过滤掉？
                }
                slen--;//长度减1
            }
        }
    }
    slen = (slen>4)?4:slen;//如果剩余长度大于4 ，就取四位
    String bString = cString;

    for (uint8_t i = 0; i < 4 - slen; i++)
    {
        bString = " " + bString;//再前面加空，凑够四位
    } 
       
    uint8_t m=0;
    for (uint8_t i = 0; i<4; i++) 
    {
        if(bString.charAt(i)>=48)//大于字符0
        {
            bool showdot=false;
            uint8_t num=0xFF;
            if(buf[m]!=100)
            {           
                if((buf[m]-1 + (4-slen))==(i))
                {
                    showdot=true;
                    m++;
                }
            }
            if(bString.charAt(i)<=57)//小于字符9
            {
                num=(uint8_t)bString.charAt(i)-48;
            }
            else if(bString.charAt(i)>=65 && bString.charAt(i)<=70)//大于字符A，小于字符F
            {
                num=(uint8_t)bString.charAt(i)-55;
            }
            else if(bString.charAt(i)>=97 && bString.charAt(i)<=102)//大于字符a，小于字符f
            {
                num=(uint8_t)bString.charAt(i)-87;
            }
            if(num!=0xff)
            {
                showNum(i+1,num,showdot);
            }
            else
            {
                clearTheDisplay(i+1);
            }
            
        }
        else
        {
            clearTheDisplay(i+1);
        }
        
    }

    // for(int i=0; i<5; i++)
    // {
    //     if(buf[i]!=100)//i=1
    //     {
    //         setDot(buf[i]-1 + (4-slen),true);
    //     }
    // }

}

//显示字符串
void AIP650::displayString(String Str)
{
    displayString((char *)Str.c_str());
}

void AIP650::displayString(double value) {
    displayString(String(value));
}

void AIP650::displayString(int value) {
    displayString(String(value));
}

void AIP650::displayString(long value) {
    displayString(String(value));
}



//清空显示
void AIP650::clearDisplay(void) 
{
    for (int8_t i = 1; i <= 4; i++)
    {
        // writeBytes(0x66+i*2, 0x00);
        clearTheDisplay(i);
    }
}

//清空指定位数 index 清空第几位的显示 index:1-4
void AIP650::clearTheDisplay(uint8_t index)
{
    writeBytes(0x66+index*2, 0x00);
}



void AIP650::bitDelay(void) {
    delayMicroseconds(10);
}
